Imports System.Net.Sockets
Imports System.Text

Public Class Client
    Public Event Connected(ByVal sender As Client)
    Public Event Disconnected(ByVal sender As Client)
    Public Event DataReceived(ByVal sender As Client, ByVal Data As Byte())
    Private mgID As Guid = Guid.NewGuid
    Private marData(4) As Byte
    Private CremoteIP As System.Net.IPEndPoint
    Private mobjClient As System.Net.Sockets.TcpClient
    Private Cinfo As New ClientInfo

    Public Sub New(ByVal client As System.Net.Sockets.TcpClient)
        mobjClient = client
        Cinfo.IPEndPoint = mobjClient.Client.RemoteEndPoint
        RaiseEvent Connected(Me)
        mobjClient.GetStream.BeginRead(marData, 0, 4, AddressOf DoStreamReceive, Nothing)
    End Sub

    Public ReadOnly Property ID() As String
        Get
            Return mgID.ToString
        End Get
    End Property
    Public ReadOnly Property RemoteIP() As String
        Get
            Return Cinfo.IP
        End Get
    End Property
    Public ReadOnly Property RemotePort() As String
        Get
            Return Cinfo.Port
        End Get
    End Property
    Public ReadOnly Property RemoteName() As String
        Get
            Return Cinfo.Name
        End Get
    End Property

    Private Sub DoStreamReceive(ByVal ar As IAsyncResult)
        Dim intCount As Integer
        Try
            SyncLock mobjClient.GetStream
                intCount = mobjClient.GetStream.EndRead(ar)
            End SyncLock
            If intCount < 1 Then
                RaiseEvent Disconnected(Me)
                Exit Sub
            End If

            Dim OutStream As New IO.MemoryStream(marData)
            Dim BinRead As New IO.BinaryReader(OutStream)
            Dim L As Int32 = BinRead.ReadInt32
            Do
            Loop Until mobjClient.Available >= L
            BinRead = New IO.BinaryReader(mobjClient.GetStream)
            Dim D As Byte() = BinRead.ReadBytes(L)
            RaiseEvent DataReceived(Me, D)

            SyncLock mobjClient.GetStream
                mobjClient.GetStream.BeginRead(marData, 0, 4, AddressOf DoStreamReceive, Nothing)
            End SyncLock
        Catch e As Exception
            RaiseEvent Disconnected(Me)
        End Try
    End Sub

    Public Sub Send(ByVal Data() As Byte, ByVal offset As Integer, ByVal count As Integer)
        SyncLock mobjClient.GetStream
            Dim BinWrite As New IO.BinaryWriter(mobjClient.GetStream)
            Dim Len As Int32 = Data.Length
            BinWrite.Write(Len)
            BinWrite.Write(Data)
        End SyncLock
    End Sub
    Public Sub Dispose()
        mobjClient.GetStream.Close()
        mobjClient.Close()
    End Sub
End Class
